package com.yincb.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;


@Service
public class DynamicBeanRegistrationService {
    
    private static final Logger logger = LoggerFactory.getLogger(DynamicBeanRegistrationService.class);
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @Autowired
    private DynamicCompilationService compilationService;
    
    private DefaultListableBeanFactory beanFactory;
    
    @PostConstruct
    public void init() {
        // 获取BeanFactory
        ConfigurableApplicationContext configurableContext = (ConfigurableApplicationContext) applicationContext;
        ConfigurableListableBeanFactory configurableBeanFactory = configurableContext.getBeanFactory();
        
        if (configurableBeanFactory instanceof DefaultListableBeanFactory) {
            this.beanFactory = (DefaultListableBeanFactory) configurableBeanFactory;
        } else {
            throw new RuntimeException("无法获取DefaultListableBeanFactory");
        }
    }
    
    /**
     * 注册动态Bean到Spring容器
     * @param beanName Bean名称
     * @param className 类名（包含包名）
     * @param sourceCode Java源代码
     * @return 注册结果
     */
    public BeanRegistrationResult registerBean(String beanName, String className, String sourceCode) {
        try {
            logger.info("开始注册动态Bean: {}", beanName);
            
            // 1. 编译源代码
            Class<?> beanClass = compilationService.compileClass(className, sourceCode);
            logger.debug("类编译成功: {}", className);
            
            // 2. 创建Bean定义
            BeanDefinition beanDefinition = createBeanDefinition(beanClass);
            logger.debug("Bean定义创建成功: {}", beanName);
            
            // 3. 注册Bean到Spring容器
            if (beanFactory.containsBeanDefinition(beanName)) {
                logger.warn("Bean已存在，将覆盖: {}", beanName);
                beanFactory.removeBeanDefinition(beanName);
            }
            
            beanFactory.registerBeanDefinition(beanName, beanDefinition);
            logger.info("Bean注册成功: {}", beanName);
            
            // 4. 获取Bean实例进行验证
            Object beanInstance = applicationContext.getBean(beanName);
            logger.debug("Bean实例获取成功: {}", beanName);
            
            return BeanRegistrationResult.success(beanName, className, beanInstance);
            
        } catch (Exception e) {
            logger.error("注册动态Bean失败: {}", beanName, e);
            return BeanRegistrationResult.failure(beanName, className, e.getMessage());
        }
    }
    
    /**
     * 注册动态Bean（自动生成Bean名称）
     */
    public BeanRegistrationResult registerBean(String className, String sourceCode) {
        String beanName = generateBeanName(className);
        return registerBean(beanName, className, sourceCode);
    }
    
    /**
     * 创建Bean定义
     */
    private BeanDefinition createBeanDefinition(Class<?> beanClass) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClass);
        
        // 设置作用域为单例
        builder.setScope(BeanDefinition.SCOPE_SINGLETON);
        
        return builder.getBeanDefinition();
    }
    
    /**
     * 生成Bean名称
     */
    private String generateBeanName(String className) {
        // 获取简单类名
        String simpleClassName = className;
        int lastDotIndex = className.lastIndexOf('.');
        if (lastDotIndex != -1) {
            simpleClassName = className.substring(lastDotIndex + 1);
        }
        
        // 首字母小写
        return simpleClassName.substring(0, 1).toLowerCase() + simpleClassName.substring(1);
    }
    
    /**
     * 检查Bean是否存在
     */
    public boolean isBeanExists(String beanName) {
        return applicationContext.containsBean(beanName);
    }
    
    /**
     * 获取Bean实例
     */
    public Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }
    
    /**
     * 获取Bean的类型
     */
    public Class<?> getBeanType(String beanName) {
        return applicationContext.getType(beanName);
    }
    
    /**
     * 移除动态Bean
     */
    public boolean removeBean(String beanName) {
        try {
            if (beanFactory.containsBeanDefinition(beanName)) {
                beanFactory.removeBeanDefinition(beanName);
                logger.info("Bean移除成功: {}", beanName);
                return true;
            } else {
                logger.warn("Bean不存在: {}", beanName);
                return false;
            }
        } catch (Exception e) {
            logger.error("移除Bean失败: {}", beanName, e);
            return false;
        }
    }
    
    /**
     * 获取所有注册的动态Bean名称
     */
    public String[] getAllDynamicBeanNames() {
        return applicationContext.getBeanDefinitionNames();
    }
    
    /**
     * Bean注册结果
     */
    public static class BeanRegistrationResult {
        private final boolean success;
        private final String beanName;
        private final String className;
        private final Object beanInstance;
        private final String errorMessage;
        
        private BeanRegistrationResult(boolean success, String beanName, String className, 
                                     Object beanInstance, String errorMessage) {
            this.success = success;
            this.beanName = beanName;
            this.className = className;
            this.beanInstance = beanInstance;
            this.errorMessage = errorMessage;
        }
        
        public static BeanRegistrationResult success(String beanName, String className, Object beanInstance) {
            return new BeanRegistrationResult(true, beanName, className, beanInstance, null);
        }
        
        public static BeanRegistrationResult failure(String beanName, String className, String errorMessage) {
            return new BeanRegistrationResult(false, beanName, className, null, errorMessage);
        }
        
        // Getters
        public boolean isSuccess() {
            return success;
        }
        
        public String getBeanName() {
            return beanName;
        }
        
        public String getClassName() {
            return className;
        }
        
        public Object getBeanInstance() {
            return beanInstance;
        }
        
        public String getErrorMessage() {
            return errorMessage;
        }
        
        @Override
        public String toString() {
            if (success) {
                return String.format("Bean注册成功 [name=%s, class=%s, instance=%s]", 
                                   beanName, className, beanInstance);
            } else {
                return String.format("Bean注册失败 [name=%s, class=%s, error=%s]", 
                                   beanName, className, errorMessage);
            }
        }
    }
}